import sys, os, struct
sys.path.append(os.path.join(os.path.dirname(__file__), ".."))

from bitbrook.leech_worker import LeechWorker
from threading import Thread, Lock
from bitbrook.utilities.limited_socket import LSocket

COMMAND_FORMAT = "!16sI"

class SimpleLeechStrategy(Thread):
    def __init__(self, brook, network):
        super(SimpleLeechStrategy, self).__init__()
        self._brook = brook
        self._network = network
        
        #needed for thread stopping
        self._shutdown = False
        self._shutdown_signal = Lock()
        
    def run(self):
        with self._shutdown_signal:
            while not self._shutdown:
                for chunk_idx in range(0, self._brook.number_of_chunks):
                    if not self._brook.is_chunk_complete(chunk_idx):
                        self.get_chunk(chunk_idx)
                        
    def get_chunk(self, chunk_idx):
        peer = self._network.get_random_peer()
        if not peer == None:
            (peer_ip, peer_port) = peer
            sock = LSocket()
            sock.connect((peer_ip, peer_port))
            sock.send(struct.pack(COMMAND_FORMAT, "REQUEST", chunk_idx))
            response = sock.recv(len("ACK"))
            if response == "ACK":
                leecher = LeechWorker(sock, chunk_idx, self._brook)
                leecher.start()
                leecher.join()
            
    def shutdown(self, block = True):
        self._shutdown = True
        if block:
            self._shutdown_signal.acquire()
            self._shutdown_signal.release()